/*
 * wk_slist.c
 *
 *  Created on: 2012-2-25
 *      Author: tianmax
 * 高内聚，低耦合
 *
 * 约定：
 * 		当index>当前元素个数时，默认指向程序尾部
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "wk_slist.h"
#include "wk_types.h"
#include "wk_slist_types.h"

/*内部使用函数****************************************************/
//分配节点内存
static WPSListNode wk_slist_node_alloc(){
	return (WPSListNode)calloc(1,sizeof(WSListNode));
}

/**
 * 检查输入的数据函数
 */
int wk_slist_datacheck(WSList* list,WPElement data){

	return 0;
}
/*初始化、销毁****************************************************/
//初始化链表空间,返回一个链表的头节点指针
extern WSList* wk_slist_init(wk_element_comp comp){

	/*参数检查*/
	if(!comp) return NULL;
	//创建wk_slist类型结构体
	WSList* list=(WSList*)calloc(1,sizeof(WSList));
	if(list==NULL){
		return NULL;
	}
	//创建头节点
	list->head=(WPSListNode)calloc(1,sizeof(WSListNode));
	if(list->head==NULL){
		free(list);
		list=NULL;
		return NULL;
	}
	list->head->e=NULL;
	list->head->next=NULL;
	list->current=list->head;
	list->comp=comp;

	return list;
}
extern void wk_slist_destroy_node(WPSListNode pHead){
	if(pHead==NULL){
		return;
	}
	wk_slist_destroy_node(pHead->next);
	free(pHead);
	pHead=NULL;
}
//销毁链表，pHead为头节点指针
extern void wk_slist_destroy(WSList* list){
	wk_slist_destroy_node(list->head);
	list->head=NULL;
	list->current=NULL;
	list->comp=NULL;
	free(list);
	list=NULL;
}
/*给单链表设置比较器*/
extern void wk_slist_setComp(WSList* list,wk_element_comp comp){
	list->comp=comp;
}
/*常用链表操作******************************************************/
/**
 * 得到WSList的数组元素的个数
 */
extern int wk_slist_size(WSList* list){

	return wk_slist_count(list);
}
/**
 * 得到WSList的数组元素的个数
 */
extern wlong_t wk_slist_count(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}
	wlong_t list_counter=0;
	WPSListNode pCurr=NULL;
	pCurr=list->head;

	while(pCurr->next!=NULL){
		pCurr=pCurr->next;
		list_counter++;
	}

	return list_counter;
}

/*排序操作********************************************************/
/**
 * 对List中的元素根据一定的规则进行排序
 */
extern int wk_slist_sort(WSList* list,wk_element_comp comp){

	return 0;
}

/******************************************************************/
/**
 * 负责处理负数下标,得到指向某个元素的下标
 */
extern int wk_slist_index(WSList* list,int index){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}
	int list_len=wk_slist_count(list);
	if(index>=0){
		return index;
	}else{
		//当下标为负数
		if((-index)>=list_len){
			return 0;
		}else{
			return list_len+index;
		}
	}
}

/**
 * 清除链表中的所有内容，使其成为一个空链表
 */
extern int wk_slist_clean(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}
	wk_slist_destroy_node(list->head->next);
	list->head->next=NULL;
	list->current=list->head;

	return 0;
}

/*增************************************************************************/
/**
 * 增加元素操作
 */
extern int wk_slist_insert(WSList* list,int index,WPElement data){
	/*1.参数检查*/
	if(list==NULL){
		return -1;
	}
	/*处理负数下标*/
	index=wk_slist_index(list,index);
	/**
	 * 可以等于，但是不可以大于
	 * 等于就相当于将元素插入list的尾部
	 */
	if(index>wk_slist_count(list)){
		index=wk_slist_count(list);
	}

	/**
	 * 对data不做检查，它可以为空
	 */

	/*2.函数变量初始化,创造运行条件*/
	WPSListNode pNew=wk_slist_node_alloc();
	if(pNew==NULL){
		return -1;
	}
	pNew->e=data;
	pNew->next=NULL;
	/**
	 * 获取链表元素个数
	 */
	int list_len=wk_slist_count(list);
	/*********3.函数业务处理*************/
	if(list_len==0 && index==0){
		//插入尾部
		list->current=list->head;
		list->current->next=pNew;

	}else if(list_len!=0 && index==0){
		//插入头部
		list->current=list->head;
		pNew->next=list->current->next;
		list->current->next=pNew;
	}else{
		//插入中间
		//就是将元素插入当前index元素的前面
		wk_slist_at(list,index-1);
		pNew->next=list->current->next;
		list->current->next=pNew;
	}

	/********函数业务处理结束*************/

	/*4.释放申请到的资源*/
	return 0;
}
/***************************************************************/
extern int wk_slist_append(WSList* list,WPElement data){
	/*1.参数检查*/
	if(list==NULL){
		return -1;
	}
	/**
	 * 2.函数变量初始化,创造运行条件
	 */
	WPSListNode pNew=wk_slist_node_alloc();
	if(pNew==NULL){
		return -1;
	}
	pNew->e=data;
	pNew->next=NULL;
	/**
	 * 将指针定位到尾部
	 */
	wk_slist_end(list);
	list->current->next=pNew;

	return 0;
}
/*删************************************************************************/
/**
 * 删除index位置处的元素
 */
extern int wk_slist_removeByIndex(WSList* list,int index){
	/*1.参数检查*/
	if(list==NULL){
		return -1;
	}
	int list_len=wk_slist_count(list);
	/**
	 * 处理index
	 */
	index=wk_slist_index(list,index);
	/**
	 * 不可以等于，也不可以大于
	 * 也就是不允许当前要移除的元素不存在
	 */
	if(index>=list_len){
		return -1;
	}
	/**
	 * 初始化要用到的变量
	 */
	WPSListNode pDel=NULL;
	/**
	 * 业务逻辑开始
	 */
	if(index==0){
		//要移除第一个元素
		pDel=list->head->next;
		list->head->next=pDel->next;
	}else{
		//其他情况
		//定位到要移除元素的前一个位置上
		wk_slist_at(list,index-1);
		pDel=list->current->next;
		list->current->next=pDel->next;
	}

	free(pDel);
	pDel=NULL;

	return 0;
}
/**
 * 删除比较结果相同的第一个元素
 */
extern int wk_slist_remove(WSList* list,WPElement data
		/*wk_slist_comp comp*/){
//参数检查
	if(list==NULL){
		return -1;
	}
	if(list->comp==NULL){
		return -1;
	}
//初始化函数环境
	WPSListNode pDel=NULL;
	WPSListNode pCurr=NULL;
	WPSListNode pPre=NULL;
//函数业务逻辑开始
	/**
	 * 从头到尾依次获取元素进行比较
	 * 当发现有相同的元素时，删除这个元素
	 */
	pPre=list->head;
	pCurr=list->head->next;
	//查找待删除的节点
	while(pCurr!=NULL){
		if(list->comp(pCurr->e,data)!=0){
			pPre=pCurr;
			pCurr=pCurr->next;
		}else{
			break;
		}
	}
	//待删除的节点不存在
	if(pCurr==NULL){
		return -1;
	}
	//pDel指向一个待删除的的节点
	pDel=pCurr;
	pPre->next=pCurr->next;
	free(pDel);
	pDel=NULL;
//函数业务逻辑结束，释放资源
//返回

	return 0;
}
extern int wk_slist_removeFirst(WSList* list){
	return wk_slist_removeByIndex(list,0);
}
extern int wk_slist_removeLast(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}

	int list_len=wk_slist_count(list);
	if(list_len<=0){
		return -1;
	}
	return wk_slist_removeByIndex(list,list_len-1);
}
/*查************************************************************************/
extern WPElement wk_slist_value(WSList* list,int index){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return NULL;
	}
	/**
	 * 处理index
	 */
	index=wk_slist_index(list,index);
	if(index>=wk_slist_count(list)){
		return NULL;
	}
	wk_slist_at(list,index);
	if(list->current==NULL){
		return NULL;
	}else{
		return list->current->e;
	}
}

extern WPElement wk_slist_iteratefind(WSList* list,WPElement data,
		wk_slist_iterator iterator,wk_element_iterate_do iterate_do){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return NULL;
	}
	WPElement retp=NULL;
	retp=(WPElement)iterator(list,iterate_do,data);

	return retp;
}

extern WPElement wk_slist_find(WSList* list,WPElement data
		/*wk_slist_comp comp*/){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return NULL;
	}
	WPElement retp=NULL;
//	/**
//	 * 从头到尾依次获取元素进行比较
//	 * 当发现有相同的元素时，返回当前这个元素
//	 */
//	wk_slist_begin(list);
//	while(wk_slist_hasNext(list)){
//		if(comp(wk_slist_getcurrent(list),(WPElement)data)==0){
//			retp=wk_slist_getcurrent(list);
//			break;
//		}
//		wk_slist_next(list);
//	}
//
//	if(comp(wk_slist_getcurrent(list),(WPElement)data)==0){
//		retp=wk_slist_getcurrent(list);
//	}

	/**
	 * 函数业务逻辑
	 */
	WPSListNode pCurr=NULL;
	pCurr=list->head->next;
	while(pCurr != NULL){
		if(list->comp(pCurr->e,(WPElement)data)!=0){
			pCurr=pCurr->next;
		}else{
			retp=pCurr->e;
			break;
		}
	}

	return retp;
}

extern int wk_slist_findIndex(WSList* list,WPElement data
		/*wk_slist_comp comp*/){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}
	WPElement retp=NULL;
	int index=0;
	/**
	 * 从头到尾依次获取元素进行比较
	 * 当发现有相同的元素时，返回当前这个元素
	 */
	wk_slist_begin(list);
	while(wk_slist_hasNext(list)){
		retp=wk_slist_getcurrent(list);
		if(list->comp(retp,(WPElement)data)==0){
			return index;
		}
		wk_slist_next(list);
		index++;
	}
	return -1;
}
/**
 * 获取当前链表指针指向位置的元素的值
 */
extern WPElement wk_slist_getcurrent(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return NULL;
	}
	if(list->current==NULL){
		return NULL;
	}else{
		return list->current->e;
	}
}
/*改************************************************************************/
extern int wk_slist_replaceByIndex(WSList* list,int index,WPElement data){
	/*1.参数检查*/
		if(list==NULL){
			return -1;
		}
		/*处理负数下标*/
		index=wk_slist_index(list,index);
		/**
		 * 要替换元素的位置必须存在，否则出错
		 */
		if(index>=wk_slist_count(list)){
			return -1;
		}
		/**
		 * 对data不做检查，它可以为空
		 */
		/*处理函数业务逻辑*/
		wk_slist_at(list,index);
		list->current->e=data;

		return 0;
}

extern int wk_slist_replace(WSList* list,WPElement olddata,WPElement newdata
		/*wk_slist_comp comp*/){

//参数检查
	if(list==NULL){
		return -1;
	}
	if(list->comp==NULL){
		return -1;
	}
//初始化函数环境
	WPSListNode pCurr=NULL;
//函数业务逻辑开始
	/**
	 * 从头到尾依次获取元素进行比较
	 * 当发现有相同的元素时，删除这个元素
	 */
	pCurr=list->head->next;
	//查找待删除的节点
	while(pCurr!=NULL){
		if(list->comp(pCurr->e,olddata)!=0){
			pCurr=pCurr->next;
		}else{
			break;
		}
	}
	//待修改的节点不存在
	if(pCurr==NULL){
		return -1;
	}
	//pCurr指向一个待替换的节点
	pCurr->e=newdata;

//函数业务逻辑结束，释放资源
//返回

	return 0;
}
/**************************************************************************/
extern int wk_slist_push_front(WSList* list,WPElement data){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}

	return wk_slist_insert(list,0,data);
}

extern int wk_slist_push_back(WSList* list,WPElement data){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return -1;
	}

	return wk_slist_append(list,data);
}
/**********************************************************/
extern void wk_slist_pop_front(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
	wk_slist_removeByIndex(list,0);
}

extern void wk_slist_pop_back(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}

	int list_len=wk_slist_count(list);
	if(list_len<=0){
		return;
	}
	wk_slist_removeByIndex(list,list_len-1);
}
/********************************************************/
/**
 * 链表当前指针操作
 * 将指针指向头节点
 */
extern void wk_slist_head(WSList* list){
	/*参数检查*/
	if(list==NULL){
		return;
	}
	list->current=list->head;
}
/**
 * 链表当前指针操作
 * 将指针指向第一个元素
 */
extern void wk_slist_begin(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
		list->current=list->head->next;
}

/**
 * 将指针指向最后一个元素
 * 允许在list为空时，将指针指向头节点
 */
extern void wk_slist_end(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
	list->current=list->head;
	while(list->current->next!= NULL){
		list->current=list->current->next;
	}
}

/**
 *定位范围0-最后一个元素
 */
extern void wk_slist_at(WSList* list,int index){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
	int list_len=wk_slist_count(list);
	/**
	 * 处理index
	 */
	index=wk_slist_index(list,index);
	if(list_len<0){
		return;
	}

	if(list_len==0){
		list->current=list->head->next;
	}else{
		//有1个或者一个以上元素
		if(index>=list_len){
			index=list_len-1;
		}
		int i=0;
		list->current=list->head;
		while(list->current->next != NULL){
			list->current=list->current->next;
			if(i==index){
					break;
			}
			i++;
		}
	}
}
extern void wk_slist_next(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
	if(list->current!=NULL){
		list->current=list->current->next;
	}
}
extern void wk_slist_prev(WSList* list){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return;
	}
	/**
	 * 函数逻辑处理部分
	 */
	WPSListNode pCurr=list->current;
	/**
	 * 假如当前元素的前一个元素是头节点，则不做任何事情
	 */
	if(list->current==list->head){
		return;
	}
	list->current=list->head;
	while(list->current->next != NULL){
		if(list->current->next==pCurr){
			break;
		}
		list->current=list->current->next;
	}
}

/**
 * 当前位置是否存在下一个元素
 */
extern int wk_slist_hasNext(WSList* list){
	if(list->current==NULL){
		return 0;
	}else{
		if(list->current->next==NULL){
			return 0;
		}else{
			return 1;
		}
	}
	return 1;
}

/******************************************************/
/**
 * 遍历元素相关
 * ctx上下文
 */
extern void* wk_slist_iterate(WSList* list,wk_element_iterate_do iterate_do,void* ctx){
	/**
	 * 参数检查
	 */
	if(list==NULL){
		return NULL;
	}
	void* retp=NULL;
	wk_slist_begin(list);
	while(list->current!=NULL){
		retp=iterate_do(list->current->e,ctx);
		list->current=list->current->next;
	}
	return retp;
}

/******************************************************/
/**
 * wk_slist调试函数
 */
extern void wk_slist_debug(){

}
/*****************************************************/
